<script setup lang="ts">
import type { FormContext } from '@arco-design/web-vue/es/form/context'
import { formInjectionKey } from '@arco-design/web-vue/es/form/context'
import type { StyleValue } from 'vue'
import { getDisplayValue, getFormItemInputVNode, getFormVNode, getValueByPath } from './util'

defineOptions({
  name: 'ReadonlyFormItem',
})

const props = withDefaults(
  defineProps<{
    value?: string
    emptyText?: string
    editable?: boolean
    span?: number
    contentStyle?: object
    copyable?: boolean
  }>(),
  {
    emptyText: '--',
    editable: true,
    span: 12,
    copyable: false,
  },
)

const attrs = useAttrs()
const slots = useSlots()

const otherSlots = () => {
  const { default: _, ...rest } = slots
  return rest
}

const instance = getCurrentInstance()
const form = getFormVNode(instance!)
const formContext = inject<Partial<FormContext>>(formInjectionKey, {})
const readonly = computed<boolean>(() => (form.proxy as any).$attrs.readonly)

const inputVNode = getFormItemInputVNode(slots.default!())
const fieldValue = computed(() =>
  getValueByPath(formContext.model, attrs.field as any),
)

const displayValue = ref<any>(props.emptyText)
watch(fieldValue, async (value) => {
  displayValue.value = getDisplayValue(value, inputVNode) ?? props.emptyText
}, { immediate: true })

const contentStyle = computed<StyleValue>(() => {
  return {
    ...props.contentStyle,
  }
})
</script>

<template>
  <a-col :span>
    <a-form-item v-bind="attrs" :hide-asterisk="readonly" :disabled="!readonly && !editable">
      <template v-for="(_, name) in otherSlots()" #[name]>
        <slot :name="name" />
      </template>
      <template v-if="readonly && editable">
        <slot name="readonly">
          <a-typography-text :style="contentStyle" :copyable="copyable">
            {{ displayValue }}
          </a-typography-text>
        </slot>
      </template>
      <slot v-else />
    </a-form-item>
  </a-col>
</template>

<style scoped>

</style>
